﻿using System.Linq;
using System.Xml.Linq;

namespace TestExtensions
{
    internal class TestFailureSearch
    {
        #region Constants

        private const string FAILED_MESSAGE_FORMATTER = "{0} - {1}";

        #endregion

        #region Constructors

        internal TestFailureSearch(TestResults results)
        {
            Step = FindFailedStep(results);
            if (Step == null)
            {
                Message = "Unknown error has occurred.";
            }
            else
            {
                Message = string.Format(FAILED_MESSAGE_FORMATTER, Step.Object, Step.Details);
            }
        }

        #endregion

        #region Properties

        public TestStep Step { get; private set; }

        public string Message { get; private set; }

        #endregion

        #region Methods

        private TestStep FindFailedStep(TestResults results)
        {
            foreach (var iteration in results)
            {
                var failedStep = iteration
                    .Select(action => FindFailedStep(action.Step))
                    .Where(step => step != null)
                    .FirstOrDefault();
                if (failedStep != null)
                {
                    return failedStep;
                }
            }

            return null;
        }

        private TestStep FindFailedStep(TestStep step)
        {
            if (step.Status == "Failed")
            {
                return step
                    .Select(FindFailedStep)
                    .Where(subStep => subStep != null)
                    .DefaultIfEmpty(step)
                    .FirstOrDefault();
            }
            return null;
        }

        #endregion
    }

    public static class TestFailureSearchExtensions
    {
        public static string GetFailureMessage(this TestResults @this)
        {
            return new TestFailureSearch(@this).Message;
        }
    }
}